/////precompiled////////
#include "precompiled.h"
////////////////////////


#include "frm_control_TDate.h"

using namespace frm;
using namespace control;

// TPart //////////////////////////////////////////////////////////////////////

//
TDate::TPart::TPart(TDate *Date,int Len) : TString(Date->GetWindow()) 
{ 
  Date->AddChildLast(this,true);
  date = Date; len = Len;
}

//
void TDate::TPart::SetNull()
{
  svl::TString V; V.FillToLen(len,'-');
  TString::SetValue(V);
}

//
void TDate::TPart::SetValue(int V)
{
  if( V == -1 ){ 
	if( len == 2 )
	  TString::SetValue(svl::TString() << 0 << 1);
	else
	  TString::SetValue(svl::TString() << 2001);
	return;
  }

  if (V < 10) 
	TString::SetValue(svl::TString() << 0 << V);
  else
	TString::SetValue(V);
}

//
int TDate::TPart::GetValue()
{
  return TString::GetValue().ConvertToInt(); 
}

//
bool TDate::TPart::UpdateValue(svl::TString V)
{
/************
  int Pos = Focus_GetPos(); V.DelSym(Pos+1);
  frm::TComponentString::UpdateValue(V); if (Pos+1 >= len)
  {
    TPart *Next = dynamic_cast<TPart*>(date->SearchNextChildFocusEnable(Type(),this)); 
    if (Next) { Next->Focus_SetByPos(0); }
    return false;
  }
  return true;
*************/
  return TString::UpdateValue(V);
}

//
bool TDate::TPart::Focus_SetByPos(int Pos)
{ 
  return TString::Focus_EnterByPos(Pos);
}

//
void TDate::TPart::TComponent_KeyboardKey(grf::TKeyboardKey &KeyboardKey)
{
  if (KeyboardKey.State == grf::TKeyboardKey::EState_Down)
  {
    if (KeyboardKey.Shift.IsEmpty() && KeyboardKey.Key == VK_DELETE || KeyboardKey.Key == VK_BACK)
    {
      TBeginPaint P(this);
      KeyboardKey.Key = 0; date->SetNull(); 
      date->ReupdateValue();
      date->day->Focus_SetByPos(0);
    }
    else if (KeyboardKey.Key == VK_RIGHT)
    {
      int Pos = Focus_GetPos(); if (Pos + 1 == len)
      { 
        TPart *Next = dynamic_cast<TPart*>(date->SearchNextChildFocusEnable(Type(),this)); 
        if (Next) { Next->Focus_SetByPos(0); }
        return;
      }
    }
    else if (KeyboardKey.Key == VK_LEFT)
    {
      int Pos = Focus_GetPos(); if (Pos == 0)
      { 
        TPart *Prev = dynamic_cast<TPart*>(date->SearchPrevChildFocusEnable(Type(),this)); 
        if (Prev) { Prev->Focus_SetByPos(Prev->len-1); }
        return;
      }
    }
  }
  TString::TComponent_KeyboardKey(KeyboardKey);
}

//
void TDate::TPart::TComponent_KeyboardChar(grf::TKeyboardChar &KeyboardChar)
{
  if (::isdigit(KeyboardChar.Key))
  {
    svl::TString V = TString::GetValue();
    V[Focus_GetPos()] = KeyboardChar.Key;

    TBeginPaint P(this);
    UpdateValue(V); 
    
    if (Focus_GetPos()+1 >= len)
    {
      TPart *Next = dynamic_cast<TPart*>(date->SearchNextChildFocusEnable(Type(),this)); 
      if (Next) { Next->Focus_SetByPos(0); }
    }
    else { Focus_SetByPos(Focus_GetPos()+1); }
    
    date->isNull = false; 
	date->makeupdate();
	date->ShowCheckDate();
	date->ReupdateValue();
  }
}

//
void TDate::TPart::TComponent_FocusExit()
{
  	TString::TComponent_FocusExit();
}

// TDate //////////////////////////////////////////////////////////////////////

//
TDate::TDate(TWindow &Window) : TLine(Window) 
{ 
  Width_ChildrenSum().Height_ChildrenMaxBase().DirectChildren_Horz()
   .WAlignChildren_Begin().HAlignChildren_BeginBase();

  day   = new TPart(this,2); sep1 = new TSeparator(this);
  month = new TPart(this,2); sep2 = new TSeparator(this);
  year  = new TPart(this,4);
  
  SetNull();
}

//
void TDate::SetNull() 
{ 
  isNull = true; 
  day->SetNull(); 
  month->SetNull(); 
  year->SetNull(); 
  ShowCheckDate();
}

//
void TDate::SetValue(svl::TVariant V) 
{ 
  if (V.IsNull()) 
    { SetNull(); } 
  else 
    { SetValue(V.DateTime()); } 
}

//
void TDate::SetValue(svl::TDateTime V) 
{ 
  day  ->SetValue(V.GetDay());
  month->SetValue(V.GetMonth());
  year ->SetValue(V.GetYear());
  
  isNull = false;
}

//
bool TDate::UpdateValue(svl::TDateTime V){
  day  ->SetValue(V.GetDay());
  month->SetValue(V.GetMonth());
  year ->SetValue(V.GetYear());
  
  isNull = false;
  return true;
}

//
svl::TDateTime TDate::GetValue()
{
  svl::TDateTime DT; 
  DT.SetDate( year->GetValue(), month->GetValue(), day->GetValue() );
  return DT;
}

//
void TDate::ReupdateValue()
{
  TBeginPaint P(this);

  day  ->ReupdateValue(); 
  month->ReupdateValue(); 
  year ->ReupdateValue(); 

  InsertPaint(this);
  ReupdateSize();
}

//
TDate &TDate::SetStyle(TString::TStyle &V)
{
  TBeginPaint P(this);

  day  ->SetStyle(V); sep1->SetStyle(V);
  month->SetStyle(V); sep2->SetStyle(V);
  year ->SetStyle(V);

  return *this;
}

//
void TDate::TComponent_FocusExit()
{
  TBeginPaint P(this);

  svl::TDateTime DT; 
  if ( !DT.SetDate( year->GetValue(), month->GetValue(), day->GetValue() ) ){ 
	SetNull(); ReupdateSize(); 
  }
                  
  TLine::TComponent_FocusExit();
}

//
void TDate::ShowCheckDate()
{
  struct TStyleError : public TLine::TStyle
  {
    TStyleError()
    {
      Normal  .Filler.Set(filler::TLineHorzBottom(255,0,0 ,2));
      Focused .Filler.Set(filler::TLineHorzBottom(255,0,0 ,2));
      Selected.Filler.Set(filler::TLineHorzBottom(255,0,0 ,2));
    }
  };
  static TStyleError   StyleError;
  static TLine::TStyle StyleNormal;

  if (IsNull())
    { TLine::SetStyle(StyleNormal); }
  else if (svl::TDateTime().SetDate(year->GetValue(),month->GetValue(),day->GetValue()))
    { TLine::SetStyle(StyleNormal); }
  else
    { TLine::SetStyle(StyleError); }
}



void TDate::makeupdate(){
	svl::TString a;
	a << day->frm::control::TString::GetValue() 
	  << sep1->frm::control::TString::GetValue() 
	  << month->frm::control::TString::GetValue() 
	  << sep2->frm::control::TString::GetValue() 
	  << year->frm::control::TString::GetValue();
	UpdateValue( svl::TDateTime(a) );
}